package com.lsh.oms.worker.service.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lsh.base.common.json.JsonUtils;
import com.lsh.oms.api.model.es.OrderHeadForEs;
import com.lsh.oms.core.enums.OrderStatus;
import com.lsh.oms.core.enums.TaskStatus;
import com.lsh.oms.core.enums.TaskType;
import com.lsh.oms.core.enums.Valid;
import com.lsh.oms.core.exception.BusinessException;
import com.lsh.oms.core.model.order.OrderDetail;
import com.lsh.oms.core.model.order.OrderHead;
import com.lsh.oms.core.model.po.OmsTask;
import com.lsh.oms.core.proxy.model.OrderSplitRequest;
import com.lsh.oms.core.proxy.model.PoCodeSplit;
import com.lsh.oms.core.proxy.model.SplitItem;
import com.lsh.oms.core.proxy.service.EsProxy;
import com.lsh.oms.core.proxy.service.MisProxy;
import com.lsh.oms.core.proxy.service.PsiProxy;
import com.lsh.oms.core.service.order.OrderQueryService;
import com.lsh.oms.core.service.order.OrderUpdateService;
import com.lsh.oms.core.service.sms.ShortMessageHandler;
import com.lsh.oms.core.service.split.IOrderSplitService;
import com.lsh.oms.core.utils.model.Good;
import com.lsh.oms.worker.service.base.OmsSimpleElasticJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author peter
 */
@Slf4j
@Component
public class OrderSplitJop extends OmsSimpleElasticJob {

    private static Integer MAX_MISCREATEORDERTIME = 20;

    @Autowired
    private OrderQueryService orderQueryService;

    @Autowired
    private IOrderSplitService orderSplitService;

    @Autowired
    private OrderUpdateService orderUpdateService;

    @Autowired
    private MisProxy misProxy;

    @Autowired
    private ShortMessageHandler shortMessageHandler;

    @Autowired
    private PsiProxy psiProxy;

    @Autowired
    private EsProxy esProxy;

    @Override
    protected Integer getFetchSize() {
        return 50;
    }

    @Override
    protected TaskType getTaskType() {
        return TaskType.ORDER_SPLIT;
    }

    @Override
    protected List<Integer> dealTaskStatus() {
        return Arrays.asList(TaskStatus.TASK_UN_DEAL.getCode(), TaskStatus.TASK_DEAL_FAIL.getCode());
    }

    @Override
    protected int process(OmsTask omsTask) {
        boolean splitFlag;
        try {
            Long orderCode = Long.valueOf(omsTask.getRefCode());

            OrderHead orderHeadParent = orderQueryService.findByCode(orderCode, true, true);

            Integer timestamp = (int) (System.currentTimeMillis() / 1000);
            Integer misCreateOrderTime = timestamp - orderHeadParent.getCreateTime();

            if (misCreateOrderTime < MAX_MISCREATEORDERTIME) {
                log.info("{} 订单的拆单时间是 {},拆单时间间隔太短,下次任务拆单", orderCode, misCreateOrderTime);
                return 0;
            }

            if (orderHeadParent.getOrderStatus() != OrderStatus.ORDER_SPLIT_CHECK.getIndex()) {
                log.info("【{}】 此订单不需要拆单，或者 拆单已完成 ，订单状态是 【{}】", orderCode, orderHeadParent.getOrderStatus());
                return -1;
            }

            if (orderHeadParent.getValid().equals(Valid.DISABLE.getValue())) {
                log.info("【{}】 拆单已完成 ，订单状态是 【{}】", orderCode, orderHeadParent.getOrderStatus());
                return 1;
            }

            log.info("orderCode {} 开始拆单", orderCode);
            splitFlag = this.processOne(orderHeadParent);

        } catch (BusinessException ex) {
            log.error("拆单处理异常 " + ex.getMessage(), ex);
            splitFlag = false;
        }

        return splitFlag == true ? 1 : -1;
    }

    /**
     * @param orderHeadParent
     * @return
     */
    private boolean processOne(OrderHead orderHeadParent) {

        Map<String, OrderHead> orderHeadSplitMap = orderSplitService.split(orderHeadParent);
        Long orderCode = orderHeadParent.getOrderCode();
        if (CollectionUtils.isEmpty(orderHeadSplitMap)) {
            log.info("拆单失败");
            return false;
        }

        log.info(orderCode + "拆单库存信息 : orderDetailMap is {}", JSON.toJSONString(orderHeadSplitMap));
        // 不需要拆单
        if (orderHeadSplitMap.size() == 1) {
            // TODO 修改订单状态 ，更新ES
            log.info("orderCode {} 不拆单", orderCode);
            return this.dealNoSplitOrder(orderHeadParent, orderHeadSplitMap);
        }

        Long phcode = orderHeadParent.getOrderCode();
        //请求计算服务  更新拆单结果信息 接口幂等处理
        OrderSplitRequest orderSplitRequest = new OrderSplitRequest();
        orderSplitRequest.setOrderId(phcode);
        List<SplitItem> splitItems = new ArrayList<>();
        for (Map.Entry<String, OrderHead> orderHeadEntry : orderHeadSplitMap.entrySet()) {
            String splitRule = orderHeadEntry.getKey();
            SplitItem splitItem = new SplitItem();
            String[] keys = splitRule.split(":");
            if (keys.length != 3) {
                log.info(orderHeadParent.getOrderCode() + " : dealNoSplitOrder 拆单失败");
                return false;
            }

            splitItem.setSplitRule(splitRule);
            splitItem.setOrderDc(keys[2]);

            OrderHead orderHead = orderHeadEntry.getValue();
            List<OrderDetail> orderDetailList = orderHead.getDetails();
            log.info("atp split order orderHead is {}", JSON.toJSONString(orderHead));
            List<Map<String, String>> itemNos = new ArrayList<>();
            List<Map<String, String>> itemCodes = new ArrayList<>();
            for (OrderDetail orderDetail : orderDetailList) {

                Integer itemCode = orderDetail.getItemCode();
                if (itemCode > 0) {
                    Map<String, String> itemMap = new HashMap<>(2);
                    itemMap.put("item_code", itemCode + "");

                    itemCodes.add(itemMap);
                } else {
                    JSONObject detailExt = JSON.parseObject(orderDetail.getDetailExt());
                    Map<String, String> itemMap = new HashMap<>(2);
                    itemMap.put("item_no", detailExt.getString("itemNo"));

                    itemNos.add(itemMap);
                }
            }

            if (!CollectionUtils.isEmpty(itemNos) && !CollectionUtils.isEmpty(itemCodes)) {
                log.info("拆单失败,行项目有问题 itemNos {},itemCodes {}", JSON.toJSONString(itemNos), JSON.toJSONString(itemCodes));
                return false;
            }

            splitItem.setItemNos(itemNos);
            splitItem.setItemCodes(itemCodes);
            splitItems.add(splitItem);
        }

        orderSplitRequest.setSplitItems(splitItems);
        //提交拆单结果
        JSONObject content = this.misProxy.splitPush(orderSplitRequest, orderHeadParent.getVenderId());
        if (content == null) {
            return false;
        }
        log.info("订单 ({}) mis 【拆单及创建订单】【返回结果】 {}", orderCode, content.toJSONString());
        if (!content.getBoolean("sign")) {
            return false;
        }

        return true;
    }

    /**
     * @param orderHeadParent
     * @return
     */
    private boolean processTwo(OrderHead orderHeadParent) {

        Map<String, OrderHead> orderHeadMap = orderSplitService.split(orderHeadParent);
        Long orderCode = orderHeadParent.getOrderCode();
        if (CollectionUtils.isEmpty(orderHeadMap)) {
            log.info("拆单失败");
            return false;
        }

        if (orderHeadMap.size() != 1) {
            log.info("拆单失败");
            return false;
        }
        log.info(orderCode + ": orderDetailMap is {}", JSON.toJSONString(orderHeadMap));

        String splitDc = orderHeadMap.keySet().iterator().next();
        OrderHead orderHead = orderHeadMap.get(splitDc);

        List<OrderDetail> orderDetailList = orderHead.getDetails();
        Map<String, Good> code2GoodsMaps = new HashMap<>();
//                goodsServiceProxy.requestCode2Goods(orderCode, splitDc, orderHeadParent.getVenderId());
        Map<Long, String> skuCode2codeMap = new HashMap<>();
        for (Good good : code2GoodsMaps.values()) {
            skuCode2codeMap.put(good.getSkuCode(), good.getSupplySkuCode());
        }
        Map<String, List<OrderDetail>> code2OrderDetailMap = new HashMap<>();
        for (OrderDetail orderDetail : orderDetailList) {

            String code = skuCode2codeMap.get(orderDetail.getSkuCode());

            List<OrderDetail> code2OrderDetailList = code2OrderDetailMap.get(code);
            if (CollectionUtils.isEmpty(code2OrderDetailList)) {
                code2OrderDetailList = new ArrayList<>();

                code2OrderDetailMap.put(code, code2OrderDetailList);
            }

            code2OrderDetailList.add(orderDetail);
        }

        // 请求进销存的供货码列表
        JSONObject req = new JSONObject();
        req.put("owner_id", 3);
        req.put("goods_ids", code2GoodsMaps.keySet());
        List<PoCodeSplit> poCodeSplitList = this.psiProxy.code2venderId(req.toJSONString(), orderCode);
        if (CollectionUtils.isEmpty(poCodeSplitList)) {
            return false;
        }
        log.info("查询文固供商信息结果 " + JSON.toJSONString(poCodeSplitList));
        if (poCodeSplitList.size() == 1) {
            // TODO 修改订单状态 ，更新ES
            return this.dealNoSplitOrder(orderHeadParent, orderHeadMap);
        }
//        for循环结果 初始化拆单
        OrderSplitRequest orderSplitRequest = new OrderSplitRequest();
        orderSplitRequest.setOrderId(orderCode);
        List<SplitItem> splitItems = new ArrayList<>();
        for (PoCodeSplit poCodeSplit : poCodeSplitList) {
            String splitRule = splitDc + ":" + poCodeSplit.getVenderId();
            SplitItem splitItem = new SplitItem();

            splitItem.setSplitRule(splitRule);
            splitItem.setOrderDc(splitDc);
            List<String> codes = poCodeSplit.getCodes();
            List<Map<String, String>> itemNos = new ArrayList<>();
            for (String code : codes) {

                List<OrderDetail> codeOrderDetailList = code2OrderDetailMap.get(code);

                for (OrderDetail orderDetail : codeOrderDetailList) {

                    JSONObject detailExt = JSON.parseObject(orderDetail.getDetailExt());
                    Map<String, String> itemMap = new HashMap<>();
                    itemMap.put("item_no", detailExt.getString("itemNo"));

                    itemNos.add(itemMap);
                }
            }

            splitItem.setItemNos(itemNos);
            splitItems.add(splitItem);
        }

        orderSplitRequest.setSplitItems(splitItems);
        //提交拆单结果
        JSONObject content = this.misProxy.splitPush(orderSplitRequest, orderHeadParent.getVenderId());

        if (content == null) {
            return false;
        }
        log.info("订单 ({}) mis 【拆单及创建订单】【返回结果】 {}", orderCode, content.toJSONString());

        if (!content.getBoolean("sign")) {
            return false;
        }

        return true;
    }

    private boolean dealNoSplitOrder(OrderHead orderHeadParent, Map<String, OrderHead> orderDetailMap) {
        // TODO 修改订单状态 ，更新ES
        String splitRule = orderDetailMap.keySet().iterator().next();
        String[] keys = splitRule.split(":");
        if (keys.length != 3) {
            log.info(orderHeadParent.getOrderCode() + " : dealNoSplitOrder 拆单失败");
            return false;
        }

        String splitDc = keys[2];
        if (this.processNoSplitOrder(orderHeadParent, splitDc)) {

            OrderHead filter = new OrderHead();
            filter.setOrderCode(orderHeadParent.getOrderCode());

            OrderHead entry = new OrderHead();
            entry.setOrderStatus(OrderStatus.ORDER_COMMITING_OFC.getIndex());
            entry.setExt(orderHeadParent.getExt());
            entry.setAddressInfo(orderHeadParent.getAddressInfo());
            log.info("拆单接口 修改数据库参数" + JSON.toJSONString(entry));
            if (orderUpdateService.updateOrderHead(entry, filter) > 0) {
                // TODO 状态优化
                orderHeadParent.setOrderStatus(OrderStatus.ORDER_COMMITING_OFC.getIndex());
                if (orderHeadParent.getStorageType() == 2) {
                    shortMessageHandler.pushNotify(orderHeadParent);
                }

                return this.updateOrderEs(orderHeadParent);
            }
        }

        return false;
    }

//    /**
//     * 3000区域下，云仓的订单，需要在订单行项目上，填充未税成本、含税成本、税率、扣点等信息
//     *
//     * @param orderHead
//     * @param orderDc
//     */
//    private void needInsertFillTaxRateTask(OrderHead orderHead, String orderDc) {
//
//        try {
//            int userType = OrderFactory.getUserType(orderHead);
//            if (UserType.KA.getIndex() == userType) {
//                this.orderCreateService.addFillPriceAndRateTask(String.valueOf(orderHead.getOrderCode()), orderHead.getVenderId());
//            }
//        } catch (Exception e) {
//            log.error("判断订单，是否是KA卖票异常", e);
//        }
//    }

    /**
     * @param orderHead
     * @return
     */
    private Boolean updateOrderEs(OrderHead orderHead) {

        String logSign = orderHead.getOrderCode() + "";
        OrderHeadForEs ohEs = new OrderHeadForEs();
        ohEs.setOrderCode(orderHead.getOrderCode());
        ohEs.setOrderStatus(orderHead.getOrderStatus());

        JSONObject extJson = JSON.parseObject(orderHead.getExt());
        String providerId = extJson.getString("providerId");

        String orderDc = extJson.getString("orderDc");

        ohEs.setProviderId(providerId);
        ohEs.setOrderDc(orderDc);

        log.info("({}) jop order update ES入参订单是: {}", logSign, JsonUtils.obj2Json(ohEs));

        return esProxy.editIndex(ohEs, logSign);
    }

    /**
     * @param orderHeadParent
     * @param splitDc
     * @return
     */
    private boolean processNoSplitOrder(OrderHead orderHeadParent, String splitDc) {

        List<OrderDetail> orderDetailList = orderHeadParent.getDetails();
        if (CollectionUtils.isEmpty(orderDetailList)) {
            return false;
        }

        OrderDetail detail = orderDetailList.get(0);
        JSONObject detailExt = JSON.parseObject(detail.getDetailExt());
        String providerId = detailExt.getString("providerId");
        String providerName;
        if (StringUtils.isEmpty(providerId)) {
            return false;
        }
        providerName = misProxy.requestProviderName(providerId, orderHeadParent.getVenderId());

        JSONObject headExt = JSON.parseObject(orderHeadParent.getExt());
        headExt.put("providerId", providerId);
        headExt.put("providerName", providerName);
        headExt.put("orderDc", splitDc.trim());
        headExt.put("parentHaveCloudChildren", "0");

        orderHeadParent.setExt(headExt.toJSONString());
        // 3000区域下，云仓的订单，需要在订单行项目上，填充未税成本、含税成本、税率、扣点等信息
//        this.needInsertFillTaxRateTask(orderHeadParent, splitDc);

        return true;
    }

}
